from typing import Optional, Union, List

import uvicorn
from fastapi import FastAPI, Cookie, Header, Response, Path, HTTPException, status, Request, Depends
from fastapi.responses import JSONResponse
from fastapi.openapi.docs import get_swagger_ui_html
from pydantic import BaseModel, Field
from starlette.staticfiles import StaticFiles

# 所有的api都依赖这个函数
async def set_charset():
    print("set utf-8")

# 创建 FastAPI 应用实例，并把默认的/docs请求禁用
# debug表示是否开启调试模式，默认是False
app = FastAPI(docs_url=None,debug=True,dependencies=[Depends(set_charset)])
app.mount("/static", StaticFiles(directory="../static"), name="static")    # 静态文件

@app.get("/docs", include_in_schema=False)
def custom_swagger_ui():
    return get_swagger_ui_html(
        openapi_url = "/openapi.json",
        title = "Swagger UI for FastAPI",
        swagger_js_url="/static/swagger-ui-bundle.min.js",
        swagger_css_url="/static/swagger-ui.min.css"
    )

# 这里一个独立的模块中进行的一些操作，这些操作不需要写到每个具体的路由操作函数中
async def verify_auth(api_token: Optional[str] = Header(None,alias="api-token")):
    if not api_token:
        raise HTTPException(status_code=status.HTTP_401_UNAUTHORIZED,detail="未授权")



def total_param(total_page:Optional[int] = 1):
    return total_page

# 定义一个被依赖函数,这个依赖函数中的某一项又依赖其它的函数
def pageInfo_params(page_index:Optional[int] = 1,page_size:Optional[int] = 10,total:Optional[int]=Depends(total_param)):
    return {"page_index":page_index,"page_size":page_size,"total":total}

# FastAPI发现这里的路由函数参数是Depends，那么就会把传进来的参数转送到指定的被依赖函数：pageInfo_params
# pageInfo_params函数返回的是dict
@app.get("/items")
async def get_items(page_info: dict = Depends(pageInfo_params)):
    return page_info

class PageInfo:
    def __init__(self,page_index:Optional[int] = 1,page_size:Optional[int] = 10,total:Optional[int]=Depends(total_param)):
        self.page_index = page_index
        self.page_size = page_size
        self.total = total

# 这里我们的依赖项是PageInfo类，它初始化是一个PageInfo的实例
# 这里/users 会依赖verify_auth
@app.get("/users",dependencies=[Depends(verify_auth)])
async def get_users(page_info: PageInfo = Depends(PageInfo)):
    return {"page_index": page_info.page_index, "page_size": page_info.page_size, "total": page_info.total}

# 这里实际上我们可以省略Depends()中的类，我们的参数就指定了一个类是PageInfo，它自己就可以确定依赖的是PageInfo类了
@app.get("/goods")
async def get_users(page_info: PageInfo = Depends()):
    return {"page_index": page_info.page_index, "page_size": page_info.page_size}








if __name__ == '__main__':
    uvicorn.run("main:app", host="127.0.0.1", port=8010, reload=True)